const fs = require('fs-extra')
const path = require('path')
const chalk = require('chalk')
const consoleUtil = require('./util/consoleUtil')
const validateProjectName = require('validate-npm-package-name')
const inquirer = require('inquirer')
const Creator = require('./Creator')
const templateList = require('./templateList')
const spinner = require('./spinner')

async function create(appName, options) {
  const cwd = options.cwd || process.cwd()
  const inThisDir = appName === '.'
  const projectName = inThisDir ? path.relative('../', cwd) : appName
  const targetDir = path.resolve(cwd, appName || '.')

  const result = validateProjectName(projectName)
  if(!result.validForNewPackages) {
    console.error(chalk.red( `Invalid app name: ${projectName}`))
    result.errors && result.errors.forEach(err => {
      console.error(chalk.red.dim('Error: ' + err))
    })
    result.warnings && result.warnings.forEach(warn => {
      console.error(chalk.red.dim('Warning: ' + warn))
    })
    process.exit(1)
  }

  options = {...options, appName}

  if (fs.existsSync(targetDir)) {
    if (options.force) {
      fs.removeSync(targetDir)
    } else {
      consoleUtil.clear()
      if (inThisDir) {
        const { ok } = await inquirer.prompt([
          {
            name: 'ok',
            type: 'confirm',
            message: `Generate project in current directory?`
          }
        ])
        if (!ok) return
      } else {
        const { action } = await inquirer.prompt([
          {
            name: 'action',
            type: 'list',
            message: `Target directory ${chalk.cyan(targetDir)} already exists. Pick an action:`,
            choices: [
              { name: 'overwrite', value: 'overwrite' },
              { name: 'cancel', value: false }
            ]
          }
        ])
        if (!action) {
          return
        } else if (action === 'overwrite') {
          console.log()
          console.log(`removing ${chalk.cyan(targetDir)}...`)
          fs.removeSync(targetDir)
        }
      }
    }
  }

  const {action} = await inquirer.prompt([
    {
      name: 'action',
      type: 'list',
      message: `which template do you like?`,
      choices: templateList
    }
  ])
  
  if (!action) {
    process.exit(1)
  } else {
    options.cliUtil = action
  }

  // creator
  const creator = new Creator(projectName, targetDir)
  await creator.create(options)
}

module.exports = (...args) => {
  return create(...args).catch(err => {
    spinner.stopSpinner(false) // do not persist
    console.error(err)
    process.exit(1)
  })
}